﻿@implements IDisposable

<a @ref=@linkRef class="demo-anchor" href="@Link" id="@GetId()" />
@code {
    [Parameter] public string Link { get; set; }

    [CascadingParameter(Name = "ScrollToTargetLocked")] bool ScrollLocked { get; set; }

    [Inject] NavigationManager NavigationManager { get; set; }

    [Inject] IJSRuntime JsRuntime { get; set; }

    ElementReference linkRef;

    protected override void OnInitialized()
    {
        base.OnInitialized();

        NavigationManager.LocationChanged += OnLocationChanged;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
            await ScrollToIfNeeded(NavigationManager.Uri);
    }

    protected override bool ShouldRender() {
        return ScrollLocked || base.ShouldRender();
    }

    void OnLocationChanged(object sender, LocationChangedEventArgs args)
    {
        InvokeAsync(async () => { await ScrollToIfNeeded(args.Location); });
    }

    async Task ScrollToIfNeeded(string uri)
    {
        if(!ScrollLocked && uri.EndsWith(Link, StringComparison.OrdinalIgnoreCase)) {
            var uriFragment = NavigationManager.ToAbsoluteUri(uri).Fragment;
            if(!string.IsNullOrEmpty(uriFragment) && Link.EndsWith(uriFragment))
                await JsRuntime.InvokeVoidAsync("Element.prototype.scrollIntoView.call", linkRef);
        }
    }

    string GetId() {
        if(ScrollLocked)
            return null;
        var linkParts = Link.Split('#');
        return linkParts.Length > 1 ? linkParts[1] : null;
    }

    void IDisposable.Dispose()
    {
        NavigationManager.LocationChanged -= OnLocationChanged;
    }
}
